﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Mjudoku
{
    public partial class Form1 : Form, View
    {
        private Controller controller;
        private Model model;

        public Form1(Controller control, Model model)
        {
            InitializeComponent();
            controller = control;
            this.model = model;
        }

        private Control[,] arrayObjects;

        public void prepareFirstDraw(int blockSize, int arraySize)
        {
            this.Menu = new MainMenu();
            MenuItem quit = new MenuItem("Quit");
            MenuItem checkSudoku = new MenuItem("Check sudoku");
            MenuItem settings = new MenuItem("Settings");

            quit.Click += controller.quit_Click;
            checkSudoku.Click += controller.check_Click;
            settings.Click += settings_Click;

            this.Menu.MenuItems.Add(checkSudoku);
            this.Menu.MenuItems.Add(settings);
            this.Menu.MenuItems.Add(quit);
            


            //specify size of window
            int windowHeight = Settings.getInstance().WindowHeight, windowWidth = Settings.getInstance().WindowWidth;
            //specify margin from edge to control
            int objectMarginValue = Settings.getInstance().ObjectMarginValue;            
            //specify margin from one block to another block
            int blockMarginValue = Settings.getInstance().BlockMarginValue;

            int objectHeight = (windowHeight - (arraySize + blockSize) * objectMarginValue - (blockSize-1) * blockMarginValue) / arraySize,
                objectWidth = (windowWidth - (arraySize + blockSize) * objectMarginValue - (blockSize-1) * blockMarginValue) / arraySize;

            this.ClientSize = new Size(windowWidth - blockMarginValue, windowHeight - blockMarginValue);

            arrayObjects = new MjudokuBox[arraySize, arraySize];
            for (int i = 0; i < arrayObjects.GetLength(0); i++)
            {
                for (int j = 0; j < arrayObjects.GetLength(1); j++)
                {
                    MjudokuBox mjudokuBox = new MjudokuBox(i, j);
                    mjudokuBox.AutoSize = false;
                    mjudokuBox.Size = new Size(objectWidth, objectHeight);
                    mjudokuBox.TextChanged += controller.edit_TextChanged;                 
                    mjudokuBox.Enabled = model.isEditable(i, j);
                    mjudokuBox.Font = new Font(mjudokuBox.Font.FontFamily, Settings.getInstance().MjudokuBoxFontSize);
                    mjudokuBox.TextAlign = HorizontalAlignment.Center;                    
                    if (!mjudokuBox.Enabled)
                    {
                        mjudokuBox.Text = model.getNumber(i, j).ToString();
                    }
                    arrayObjects[i, j] = mjudokuBox;
                }
            }            
            
            for (int i = 0; i < model.getSize() / blockSize; i++)
            {
                for (int j = 0; j < model.getSize() / blockSize; j++)
                {
                    Panel block = new Panel();
                    block.Size = new Size((blockSize + 1) * objectMarginValue + blockSize * objectHeight, (blockSize + 1) * objectMarginValue + blockSize * objectWidth);
                    block.Location = new Point(i * (block.Size.Width + blockMarginValue), j * (block.Size.Width + blockMarginValue));
                    block.BackColor = Color.Aqua;
                    block.BorderStyle = BorderStyle.FixedSingle;

                    for (int ii = 0; ii < blockSize; ii++)
                    {
                        for (int jj = 0; jj < blockSize; jj++)
                        {
                            block.Controls.Add(arrayObjects[i* blockSize + ii, j * blockSize + jj]);
                            arrayObjects[i * blockSize + ii, j * blockSize + jj].Location = new Point(ii * objectWidth + (ii+1) * objectMarginValue, jj * objectHeight + (jj+1) * objectMarginValue);
                        }
                    }
                    this.Controls.Add(block);
                }
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            Environment.Exit(0);            
        }

        void settings_Click(object sender, EventArgs e)
        {
            new SettingsForm(this).Show();
        }

        void quit_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }



      public void redraw()
        {
            int arraySize = model.getSize();
            int blockSize = model.getBlockSize();
            //specify size of window
            int windowHeight = Settings.getInstance().WindowHeight, windowWidth = Settings.getInstance().WindowWidth;
            //specify margin from edge to control
            int objectMarginValue = Settings.getInstance().ObjectMarginValue;
            //specify margin from one block to another block
            int blockMarginValue = Settings.getInstance().BlockMarginValue;

            int objectHeight = (windowHeight - (arraySize + blockSize) * objectMarginValue - (blockSize - 1) * blockMarginValue) / arraySize,
                objectWidth = (windowWidth - (arraySize + blockSize) * objectMarginValue - (blockSize - 1) * blockMarginValue) / arraySize;

            this.ClientSize = new Size(windowWidth - blockMarginValue, windowHeight - blockMarginValue);


            for (int i = 0; i < arrayObjects.GetLength(0); i++)
            {
                for (int j = 0; j < arrayObjects.GetLength(1); j++)
                {
                    MjudokuBox mjudokuBox = new MjudokuBox(i, j);
                    mjudokuBox.AutoSize = false;
                    mjudokuBox.Size = new Size(objectWidth, objectHeight);
                    mjudokuBox.TextChanged += controller.edit_TextChanged;
                    mjudokuBox.Enabled = model.isEditable(i, j);
                    mjudokuBox.Font = new Font(mjudokuBox.Font.FontFamily, 32f);
                    mjudokuBox.TextAlign = HorizontalAlignment.Center;

                    if (!mjudokuBox.Enabled)
                    {
                        mjudokuBox.Text = model.getNumber(i, j).ToString();
                    }
                    arrayObjects[i, j] = mjudokuBox;
                }
            }


            this.Controls.Clear();


            for (int i = 0; i < model.getSize() / blockSize; i++)
            {
                for (int j = 0; j < model.getSize() / blockSize; j++)
                {
                    Panel block = new Panel();
                    block.Size = new Size((blockSize + 1) * objectMarginValue + blockSize * objectHeight, (blockSize + 1) * objectMarginValue + blockSize * objectWidth);
                    block.Location = new Point(i * (block.Size.Width + blockMarginValue), j * (block.Size.Width + blockMarginValue));
                    block.BackColor = Color.Aqua;
                    block.BorderStyle = BorderStyle.FixedSingle;

                    for (int ii = 0; ii < blockSize; ii++)
                    {
                        for (int jj = 0; jj < blockSize; jj++)
                        {
                            block.Controls.Add(arrayObjects[i * blockSize + ii, j * blockSize + jj]);
                            arrayObjects[i * blockSize + ii, j * blockSize + jj].Location = new Point(ii * objectWidth + (ii + 1) * objectMarginValue, jj * objectHeight + (jj + 1) * objectMarginValue);
                        }
                    }
                    this.Controls.Add(block);
                }
            }

        }
    }
}